﻿#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <iostream>



MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    ui->label_4->setVisible(false);
    ui->lineEdit_2->setVisible(false);
    //ui->lineEdit_2->;
    connect(&processet,SIGNAL(itemDClicked()), this, SLOT(processing()));//接受来自对象processet进程选择信号，并调用槽函数
    connect(this, &MainWindow::chuandicanshudizhi, &lianbiao, &cunchulianbiao::recveshu);
    connect(this, &MainWindow::chuandicanshudizhi, saomiaoth, &sasomiaotheard::recveshu);  
    connect(this, &MainWindow::chuandicanshudizhi, &gengxin, &gengxinThread::recveshu);
    connect(&gengxin, &gengxinThread::gengxin, this, &MainWindow::updatetreeWidget);
    connect(saomiaoth,&sasomiaotheard::saomiaoend, this, &MainWindow::write_treeWidget);



}

MainWindow::~MainWindow()
{
    gengxin.terminate();//强制线程停止

    delete ui;   
}


void MainWindow::processing()//记录进程相关的值
{
    ui->processname->setText("当前监视进程:"+processet.processName);
    jinchenginfor.processID = processet.processID;

    jinchenginfor.processName = processet.processName;
    //printf(" %d:%s",processID,processName.toStdString().data());
    //baseAddress = MainWindow::getModuleBaseAddress(processID,processName);
    processet.close();

}

void MainWindow::updatetreeWidget() //将链表中更新的值写入界面
{

    int count = ui->treeWidget->topLevelItemCount();
    Node* ahead=(Node*)lianbiao.returnhead();
    //std::cout << "count:"<<count << std::endl;
    for(int i=0;(ahead!=nullptr)&&(i<count);++i)
    {
        QTreeWidgetItem *item = ui->treeWidget->topLevelItem(i);
        bool ok;
        unsigned long long pid_p_2 = item->text(0).toULongLong(&ok,16);

       // for (ahead=;(ahead!=nullptr)&&(i<count);ahead = ahead->next )

            if(pid_p_2==ahead->dizhiaddress){
                switch (leixings.xuhao) {
                case 0:
                case 1:
                case 2:
                case 3:
                    if(item->text(1).toULongLong()!=ahead->value)
                    {
                        QString qdata = QString::number(ahead->value);

                        item->setText(2,item->text(1));

                        item->setText(1,qdata);
                    }
                    break;
                case 4:
                    {
                        float * a = (float *)&ahead->value;
                        if(* a != item->text(1).toFloat())
                        {
                            QString qdata = QString::number(* a);

                            item->setText(2,item->text(1));

                            item->setText(1,qdata);
                        }
                    break;
                    }
                case 5:
                    {
                        double * a = (double *)&ahead->value;
                        if(* a != item->text(1).toDouble())
                        {
                            QString qdata = QString::number(* a);

                            item->setText(2,item->text(1));

                            item->setText(1,qdata);
                        }
                    break;
                }
                case 6:
                    break;
                }
            }
            ahead = ahead->next;

    }


    int count_2 = ui->treeWidget_2->topLevelItemCount();

    HANDLE handleexe = OpenProcess(PROCESS_ALL_ACCESS,false,jinchenginfor.processID);

    for ( int a=0;a<count_2;++a ) {

        QTreeWidgetItem *item_2 = ui->treeWidget_2->topLevelItem(a);
        //QMessageBox::information(NULL,"警告",item->text(0));
        bool ok;
        unsigned long long date_2 = 0;
        int size_du;
        switch (leixings.xuhao) {
        case 0:
            size_du = 4;//4字节
            break;
        case 1:
            size_du = 1;//单字节
            break;
        case 2:
            size_du = 2;//2字节
            break;
        case 3:
            size_du = 8;//8字节
            break;
        case 4:
            size_du = 4;//单浮点
            break;
        case 5:
            size_du = 8;//双浮点
            break;
        case 6:
            size_du = 4;//字符串
            break;
        }
        unsigned long long pid_p_2 = item_2->text(0).toULongLong(&ok,16);  //PE文件映射到内存的映像数据段首偏移地址

        BOOL pid_bol_2;

        pid_bol_2 = ReadProcessMemory(handleexe, (LPVOID)pid_p_2, &date_2, size_du, NULL);

        if (pid_bol_2 == FALSE)
        {	//权限获取失败
               //QMessageBox::information(NULL,"警告","读取进程失败");
               break;
          }
           else
        {
            //std::cout<<item_2->data(2,1).toUInt()<<std::endl;
            switch (item_2->data(2,1).toUInt()) {
            case 0:
            case 1:
            case 2:
            case 3:
                if(date_2 != item_2->text(1).toULongLong())
                {
                     QString qdata = QString::number(date_2);

                     item_2->setText(1,qdata);
                }
                break;
            case 4:
               { float * a = (float *)&date_2;
                if(* a != item_2->text(1).toFloat())
                {
                     QString qdata = QString::number(* a);
                     item_2->setText(1,qdata);
                }
                break;
                }
            case 5:
                {double * a = (double *)&date_2;
                if(* a != item_2->text(1).toDouble())
                {
                     QString qdata = QString::number(* a);
                     item_2->setText(1,qdata);
                }
                break;
                }
            case 6:
                break;

            }

          }       
    }
    CloseHandle(handleexe);

}

void MainWindow::on_actionjingcheng_triggered() //点击选择进程
{
    processet.removeprocesslist();
    processet.processlist();
    processet.show();
}

void MainWindow::on_pushButton_clicked()//单击首次扫描
{
    if(jinchenginfor.processID==0)
        return;
    else
    {
        ui->pushButton->setEnabled(false);

        if(gengxinqidong){
            gengxin.terminate();
            gengxinqidong=0;
        }
        ui->label_5->setText("正在搜索中···");
        gengxinqidong =1;
        lianbiao.shoucisaomiao = 1;
        lianbiao.qingkong();
        QString data_1 = ui->lineEdit->text();
        QString data_2 = ui->lineEdit_2->text();
        //QMessageBox::information(NULL,"提示",data_1);

        bool ok1;
        leixings.xuhao = ui->comboBox->currentIndex();
        leixings.leixing = ui->comboBox->currentText();
        leixings.guize=ui->comboBox_2->currentIndex();
        switch (leixings.xuhao) {
        case 0:
               {
                    chancan->jiancha = data_1.toULongLong(&ok1);
                    chancan->jiancha2 = data_2.toULongLong();
                    chancan->processID = jinchenginfor.processID;
                    chancan->xuhao=leixings.xuhao;
                    chancan->lianbiao = &lianbiao;
                    chancan->guize = leixings.guize;

                    if(!ok1){
                        QMessageBox::information(NULL,"提示","请输入相对应类型数值");
                        ui->pushButton->setEnabled(true);
                    };

                    break;
               }
        case 1:
            {
                 chancan->jiancha = data_1.toULongLong(&ok1);
                 chancan->jiancha2 = data_2.toULongLong();
                 chancan->processID = jinchenginfor.processID;
                 chancan->xuhao=leixings.xuhao;
                 chancan->lianbiao = &lianbiao;
                 chancan->guize = leixings.guize;

                 if(!ok1){
                     QMessageBox::information(NULL,"提示","请输入相对应类型数值");
                     ui->pushButton->setEnabled(true);
                 };

                 break;
            }
        case 2:
            {
                 chancan->jiancha = data_1.toULongLong(&ok1);
                 chancan->jiancha2 = data_2.toULongLong();
                 chancan->processID = jinchenginfor.processID;
                 chancan->xuhao=leixings.xuhao;
                 chancan->lianbiao = &lianbiao;
                 chancan->guize = leixings.guize;

                 if(!ok1){
                     QMessageBox::information(NULL,"提示","请输入相对应类型数值");
                     ui->pushButton->setEnabled(true);
                 };

                 break;
            }
        case 3:
            {
                 chancan->jiancha = data_1.toULongLong(&ok1);
                 chancan->jiancha2 = data_2.toULongLong();
                 chancan->processID = jinchenginfor.processID;
                 chancan->xuhao=leixings.xuhao;
                 chancan->lianbiao = &lianbiao;
                 chancan->guize = leixings.guize;

                 if(!ok1){
                     QMessageBox::information(NULL,"提示","请输入相对应类型数值");
                     ui->pushButton->setEnabled(true);
                 };

                 break;
            }
        case 4:
            {
                 float * a = (float *) &chancan->jiancha;
                 *a = data_1.toFloat(&ok1);
                 a=(float *) &chancan->jiancha2;
                 *a = data_2.toFloat();
                 chancan->processID = jinchenginfor.processID;
                 chancan->xuhao=leixings.xuhao;
                 chancan->lianbiao = &lianbiao;
                 chancan->guize = leixings.guize;


                 //std::cout<<*a<<std::endl;

                 if(!ok1){
                     QMessageBox::information(NULL,"提示","请输入相对应类型数值");
                     ui->pushButton->setEnabled(true);
                 };

                 break;
            }
        case 5:
            {
                 double * a = (double *) &chancan->jiancha;
                 *a = data_1.toDouble(&ok1);
                 a = (double *) &chancan->jiancha2;
                 *a = data_2.toDouble();
                 chancan->processID = jinchenginfor.processID;
                 chancan->xuhao=leixings.xuhao;
                 chancan->lianbiao = &lianbiao;
                 chancan->guize = leixings.guize;


                 if(!ok1){
                     QMessageBox::information(NULL,"提示","请输入相对应类型数值");
                     ui->pushButton->setEnabled(true);
                 };

                 break;
            }
        case 6:
            {
                 break;
            }
           default:
               QMessageBox::information(NULL,"提示","请选择数值类型");
               ui->pushButton->setEnabled(true);
               break;
        }
        emit chuandicanshudizhi((void *)chancan);
        saomiaoth->start();
    };

}

void MainWindow::write_treeWidget()//向对象treeWidget中写入数据
{

    ui->treeWidget->clear();
    //saomiaoth->quit();
    //std::cout << "oo" << std::endl;
    Node* ahead =(Node*)lianbiao.returnhead();

    for (int count = 0;count<10000; count++) {

        //std::cout << count << std::endl;
        if(ahead==nullptr)
            break;

        switch (leixings.xuhao) {
        case 0:
        {
           int  value = ahead->value;
           QTreeWidgetItem *k = new QTreeWidgetItem();
           QString qdata = QString::number(value);
           //quintptr ptrValue = reinterpret_cast<quintptr>(ahead->dizhiaddress);
           QString qadd_id = QString::number(ahead->dizhiaddress, 16);

           //std::cout << "Base address: writ" << std::endl;
           k->setText(0,qadd_id);
           k->setText(1,qdata);
           k->setText(2,"待加");
           ui->treeWidget->addTopLevelItem(k);
           ahead=ahead->next;

           break;
        }
        case 1:
        {
           char  value = ahead->value;
           QTreeWidgetItem *k = new QTreeWidgetItem();
           QString qdata = QString::number(value);
           //quintptr ptrValue = reinterpret_cast<quintptr>(ahead->dizhiaddress);
           QString qadd_id = QString::number(ahead->dizhiaddress, 16);
           //std::cout << "Base address: writ" << std::endl;
           k->setText(0,qadd_id);
           k->setText(1,qdata);
           k->setText(2,"待加");
           ui->treeWidget->addTopLevelItem(k);
           ahead=ahead->next;
           break;
        }
        case 2:
        {
           WCHAR  value = ahead->value;
           QTreeWidgetItem *k = new QTreeWidgetItem();
           QString qdata = QString::number(value);
           //quintptr ptrValue = reinterpret_cast<quintptr>(ahead->dizhiaddress);
           QString qadd_id = QString::number(ahead->dizhiaddress, 16);
           //std::cout << "Base address: writ" << std::endl;
           k->setText(0,qadd_id);
           k->setText(1,qdata);
           k->setText(2,"待加");
           ui->treeWidget->addTopLevelItem(k);
           ahead=ahead->next;
           break;
        }
        case 3:
        {
           long long  value = ahead->value;
           QTreeWidgetItem *k = new QTreeWidgetItem();
           QString qdata = QString::number(value);
           //quintptr ptrValue = reinterpret_cast<quintptr>(ahead->dizhiaddress);
           QString qadd_id = QString::number(ahead->dizhiaddress, 16);
           //std::cout << "Base address: writ" << std::endl;
           k->setText(0,qadd_id);
           k->setText(1,qdata);
           k->setText(2,"待加");
           ui->treeWidget->addTopLevelItem(k);
           ahead=ahead->next;
           break;
        }
        case 4:
        {
           float* valuef=(float*)&ahead->value;
           //std::cout<<ahead->value <<std::endl;
           QTreeWidgetItem *k = new QTreeWidgetItem();
           QString qdata = QString::number(*valuef);
           //quintptr ptrValue = reinterpret_cast<quintptr>(ahead->dizhiaddress);
           QString qadd_id = QString::number(ahead->dizhiaddress, 16);
           //std::cout << value << std::endl;
           k->setText(0,qadd_id);
           k->setText(1,qdata);
           k->setText(2,"待加");
           ui->treeWidget->addTopLevelItem(k);
           ahead=ahead->next;
           break;
        }
        case 5:
        {
           double* valued=(double*)&ahead->value;
           QTreeWidgetItem *k = new QTreeWidgetItem();
           QString qdata = QString::number(*valued);
           //quintptr ptrValue = reinterpret_cast<quintptr>(ahead->dizhiaddress);
           QString qadd_id = QString::number(ahead->dizhiaddress, 16);
           //std::cout << "Base address: writ" << std::endl;
           k->setText(0,qadd_id);
           k->setText(1,qdata);
           k->setText(2,"待加");
           ui->treeWidget->addTopLevelItem(k);
           ahead=ahead->next;
           break;
        }
        }


    }
    ui->label_5->setText("搜索完毕");
    gengxin.start();
    gengxinqidong=1;
    ui->label_6->setText("匹配值个数："+QString::number(lianbiao.lianbiaogeshu));

    if(lianbiao.shoucisaomiao==1){
        ui->pushButton->setEnabled(true);
    }else{
        ui->pushButton_2->setEnabled(true);
    }
}


void MainWindow::on_treeWidget_itemDoubleClicked(QTreeWidgetItem *item, int column)//双击treeWidget对象中的项
{
    QTreeWidgetItem *k = new QTreeWidgetItem();
    k->setText(0,item->text(0));
    k->setText(1,item->text(1));
    k->setText(2,leixings.leixing);
    k->setData(2,1,leixings.xuhao);
    ui->treeWidget_2->addTopLevelItem(k);
}

void MainWindow::on_treeWidget_2_itemDoubleClicked(QTreeWidgetItem *item, int column)//双击treeWidget_2对象中的项
{
    if(column == 1){
        // 启动编辑状态
        // 设置项为可编辑状态
        item->setFlags(item->flags() | Qt::ItemIsEditable);
        ui->treeWidget_2->editItem(item, 1);
    }else if(column == 3){
        // 启动编辑状态
        // 设置项为可编辑状态
        item->setFlags(item->flags() | Qt::ItemIsEditable);
        ui->treeWidget_2->editItem(item, 3);
    }else{
        item->setFlags(item->flags()&~Qt::ItemIsEditable);//关闭可编辑状态
    }


}


void MainWindow::on_treeWidget_2_itemChanged(QTreeWidgetItem *item, int column)//数值修改后将修改后的数值写入进程
{
    bool ok;
    LPVOID dizhi = (LPVOID)item->text(0).toULongLong(&ok,16);
    //std::cout<<dizhi<<std::endl;
    HANDLE handleexe = OpenProcess(PROCESS_ALL_ACCESS,false,jinchenginfor.processID);
    int leixinga = item->data(2,1).toUInt();
    switch (leixinga)
    {
    case 0:
    {
         int data = item->text(1).toInt();

         WriteProcessMemory(handleexe,dizhi,&data,4,NULL);

         CloseHandle(handleexe);

         break;

    }
    case 1:
    {
         int data = item->text(1).toUInt();

         WriteProcessMemory(handleexe,dizhi,&data,1,NULL);

         CloseHandle(handleexe);

         break;

    }
    case 2:
    {
        unsigned long long data = item->text(1).toULongLong();

         WriteProcessMemory(handleexe,dizhi,&data,2,NULL);

         CloseHandle(handleexe);

         break;

    }
    case 3:
    {
         int data = item->text(1).toULongLong();

         WriteProcessMemory(handleexe,dizhi,&data,8,NULL);

         CloseHandle(handleexe);

         break;

    }
    case 4:
    {
        float data = item->text(1).toFloat();

         WriteProcessMemory(handleexe,dizhi,&data,4,NULL);

         CloseHandle(handleexe);

         break;

    }
    case 5:
    {
        double data = item->text(1).toDouble();

         WriteProcessMemory(handleexe,dizhi,&data,8,NULL);

         CloseHandle(handleexe);

         break;

    }
    default:
         CloseHandle(handleexe);
         break;
    }

}

void MainWindow::on_pushButton_2_clicked() //再次扫描筛选数值   需修改
{
    if(gengxinqidong){
        gengxin.terminate();
        gengxinqidong=0;
    }
    ui->label_5->setText("正在搜索中···");
    lianbiao.shoucisaomiao = 0;

    ui->pushButton_2->setEnabled(false);
    QString data_1 = ui->lineEdit->text();
    QString data_2 = ui->lineEdit_2->text();
    //QMessageBox::information(NULL,"提示",data_1);

    bool ok1;
    switch (leixings.xuhao) {
    case 0:
    case 1:
    case 2:
    case 3:
        {
             chancan->jiancha = data_1.toULongLong(&ok1);
             chancan->jiancha2 = data_2.toULongLong();
             //std::cout<<chancan->jiancha<<std::endl;
             break;
        }
    case 4:
        {
             float * a = (float *) &chancan->jiancha;
             *a = data_1.toFloat(&ok1);
             a=(float *) &chancan->jiancha2;
             *a = data_2.toFloat();
             break;
        }
    case 5:
        {
             double * a = (double *) &chancan->jiancha;
             *a = data_1.toDouble(&ok1);
             a = (double *) &chancan->jiancha2;
             *a = data_2.toDouble();
             break;
        }
    case 6:
        {
             break;
        }
       default:
           break;
    }
    saomiaoth->start();

}


void MainWindow::shanchuxiang()
{
    delete ui->treeWidget_2->currentItem();//删除的节点
}

void MainWindow::on_treeWidget_2_customContextMenuRequested(const QPoint &pos)//treeWidget_2右键删除
{

    QTreeWidgetItem* curItem=ui->treeWidget_2->itemAt(pos);  //获取当前被点击的节点
    if(curItem==NULL)return;
    QMenu *contextMenu = new QMenu(ui->treeWidget_2);//定义一个右键弹出菜单
    QAction *action = new QAction;
    action->setText(("删除"));
    //delete curItem;
    contextMenu->addAction(action);//往菜单内添加QAction   该action在前面用设计器定义了
    connect(action, SIGNAL(triggered(bool)), this,SLOT(shanchuxiang()));

    contextMenu->exec(QCursor::pos());//弹出右键菜单，菜单位置为光标位置

}


void MainWindow::on_comboBox_2_currentIndexChanged(int index)
{
    if(ui->comboBox_2->currentIndex()==3){
        ui->label_2->setText("小数值");
        ui->label_4->setVisible(true);
        ui->lineEdit_2->setVisible(true);
    }
    if(ui->comboBox_2->currentIndex()!=3){
        ui->label_2->setText("数值");
        ui->label_4->setVisible(false);
        ui->lineEdit_2->setVisible(false);
    }
}

